[contents] [prev] [next] [top] [bottom] (2 out of 7)

Defining Objects

The best way to extend ScriptX is through the use of specialized subclasses, which can then be reused in many different situations.

However, there may be circumstances where you do not want to create a new subclass, for example, if you want to change only one instance of a class to have some specific behavior. For this reason, ScriptX also allows specialization of individual instances through the object expression.

Chapter 3, "Working with Objects," described simple uses of the object expression to create an object and to set its instance variables. This section describes the full form of the expression, which allows you to define instance variables and methods, set initial instance variables, and provide a list of initial elements for container objects such as arrays.

Syntax Summary

The syntax for the object expression has an initial definition clause, a set of optional keyword arguments for initializing the object, and four main sections: instance variables, instance methods, settings, and contents.

object [ variableName ] ( classList ) 
[ keyword:value, keyword:value . . . ]
[ instance variables
. . . ]
[ instance methods
. . . ]
[ settings
. . . ]
[ contents
. . . ]
end
You must specify the sections of the expression in this order, although all of them are optional. You can use any subset of these sections to create an instance of a class with the specializations you need. Each section can be on a separate line, as shown in the syntax, or all on the same line, or in any combination.

Objects and Variable Names

The first clause of the object expression includes an optional variableName, which specifies the variable that the object is assigned to when it is created.

object [ variableName ] ( classList )
. . .
end
Like all variables, if the variableName has not been previously declared, it is automatically declared global. You can specify that variableName is to be declared locally by preceding the object expression with the local reserved word. Note that just as with local variables, you can only define a local object inside a local scope (that is, not at the top level).

(
local object myList (LinkedList)
	. . . 
end
)

The expression above creates a new instance of the class LinkedList (by calling new on LinkedList) and assigns it to the local variable myList.

The variable to which this object is assigned is automatically declared constant, which means that you cannot assign anything else to it once the object has been created. You can, however, redefine this variable to hold another object by using the object expression again with that same variable name.

If you leave off variableName, the object expression simply yields an object of the appropriate class. This allows you to nest the object expression within other expressions:

myShape := new TwoDShape \
	boundary:(object (Rect) x2:30, y2:20 end) \
	stroke:(object (Brush) color:blackColor, pattern:grayPattern \
			settings linewidth:3 end)

Objects and Inheritance

The first line of the object expression also specifies the class or classes this object is an instance of.

object [ variableName ]( classList )
. . .
end
The classList, which must be within parentheses, specifies a list of classes from which the new object inherits. This list can be a single class or a list of classes separated by commas. If you specify multiple classes in classList, all of those classes contribute to the newly created object. See "Multiple Inheritance" on page 122 for more information on objects with multiple superclasses.

If classList is not specified (that is, the parentheses are empty), then the object is a special instance of RootObject.

Redefining Objects

Each successive use of the object expression, using the same variable name, makes the old definition unavailable, effectively overwriting any specializations you may have made to that object.

You can add method definitions to any existing object using free method definitions. Free methods are described in the section "Free Method Syntax" on page 128.

Initialization Keywords

object [ variableName ] ( classList )
[ initKey:argument, initKey:argument . . . ]
. . .
end
Keyword arguments, as described in Chapter 3, "Working with Objects," are used to define the initial parameters of a new object, which may include setting the initial values of some of its instance variables. The keyword arguments that an object requires are defined by that class's init method and by the init methods defined by all its superclasses, for objects with multiple superclasses. You can look up a particular class in the ScriptX Class Reference for a list of keyword arguments that it uses.

Keyword arguments can be specified in any order, and many of them are optional. If you do not specify an optional keyword argument in the object expression, those keywords are given default values when the object is initialized (as defined by that class's init method). Again, see the ScriptX Class Reference for a list of keyword arguments for each class, including default values.

Instance Variables

The instance variables section of the object expression is used to add new instance variables to an object, just as it was used to add new instance variables to a class in the class expression.

object  [ variableName ] ( classList ) 
instance variables
varName
varName:initialValue
. . .
end
The instance variables reserved words can be shortened to instance vars, inst variables, or simply inst vars. All forms are equivalent.

Instance variable names can be specified either as names only (in which case their initial values are undefined), or they can be initialized by specifying a varName:initialValue pair separated by a colon. The initialValue of the variable can be any expression, including nested object definitions:

object lotsOfVars (Player)
	instance variables
		firstIV
		secondIV:@cowabunga
		thirdIV:object (PushButton) inst vars pb1 end
end

You can specify variable definitions on separate lines, on the same line separated by commas, or in any combination.

object foo (Array)
	instance vars
		a, b
		c:"purple"
		d:3, e:4
end

Instance Methods

object [ variableName ] ( classList )
instance methods
methodDefinition
. . .
end
The instance methods section of the object expression, followed by any number of method definitions, adds new methods or redefines existing methods for the given object. See "Defining Methods" on page 125 for more information on defining methods.

The reserved words instance methods can also be specified as inst methods. Both forms are equivalent.

Settings

object [ variableName ] ( classList )
settings
varName: value
. . .
end
The reserved word settings allows you to set initial values for instance variables defined by the class or classes this object is an instance of. You can also use the settings section to specify values for new instance variables you defined in an instance variables section. (Adding your own instance variables or instance methods to an object definition is called specialization.)

You can specify variable assignments on separate lines, on the same line separated by commas, or in any combination.

-- first create the Novel class as a template for this example
class Novel () inst vars author, title, characters end

-- now create an instance of book
object myNovel (Novel)
	inst vars
		authorsSister
settings
author:"Emily Bront\<00e9>"
title:"Wuthering Heights"
characters:#("Heathcliff","Catherine")
		authorsSister:"Charlotte Bront\<00e9>"
end

Using the settings clause is equivalent to first creating the object and then setting its instance variables with separate assignment statements. The following code is equivalent to the example above except that it does not include the specialization of adding the instance variable authorsSister.

myNovel := new Novel
myNovel.author := "Emily Bront\<00e9>"
myNovel.title := "Wuthering Heights"
myNovel.characters := #("Heathcliff","Catherine")

Using settings has the advantage of using fewer expressions to accomplish the same thing, and of having the new object be initialized with its instance variables already set to the values you require.

Contents

object [ variableName ] ( classList )
contents
element, element, element, . . .
end
The contents section of the object expression is used to specify the initial contents of objects that can hold other objects, such as collections. Chapter 7, "Collections", describes this set of utility classes and how to use them.

Each of the elements in the contents section is added to the object using the addToContents method. Objects that inherit from Collection have a default version of this method. If you are using a class or object that does not inherit from Collection, you must implement the addToContents method for the contents section to work. You can also override addToContents in this object, or in a class that this object inherits from, to change the default behavior (for example, to print a debugging message as each element is added).

A Note on Special Classes Created by object

In ScriptX, every object is by definition an instance of some class and receives its behavior and state information from that class. If an object is created by the object expression and has specializations (additional instance variables or methods) or is an instance of multiple classes, then a class for that special object does not truly exist.

To get around this paradox, when you use the object expression, ScriptX creates a special "hidden" class for the object created. In most cases you do not need to refer to or use these special classes. Be aware, however, that using the getClass function on a specialized object (particularly one that is an instance of multiple classes) may result in unusual results:

object specialObject (TwoDShape, Dragger) end
getClass specialObject
TwoDShapeDragger 


This document is part of the ScriptX Language Guide, one of the volumes of the ScriptX Technical Reference Series. ScriptX is developed by the ScriptX Engineering Team at Apple Computer, successor to the Kaleida Engineering Team at Kaleida Labs, Inc.

Copyright 1996 Apple Computer, Inc. All Rights Reserved.